import json
from typing import Dict, List, Any
from dataclasses import dataclass
import numpy as np
from pathlib import Path
import logging
from datetime import datetime
from knowledge_graph import JobKnowledgeGraph

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("CareerAssessment")

@dataclass
class AssessmentQuestion:
    """职业测评问题"""
    question_id: str
    question_text: str
    dimension: str  # 测评维度：兴趣/性格/价值观等
    options: List[Dict[str, Any]]
    weight: float = 1.0

@dataclass
class AssessmentResult:
    """测评结果"""
    user_id: str
    dimensions: Dict[str, float]  # 各维度得分
    recommended_jobs: List[str]
    compatibility_scores: Dict[str, float]  # 岗位匹配度
    timestamp: str

class CareerAssessment:
    """职业测评系统"""
    def __init__(self, kg_client: JobKnowledgeGraph):
        self.kg = kg_client
        self.questions = self._load_questions()
        self.job_profiles = self._load_job_profiles()
        
    def _load_questions(self) -> List[AssessmentQuestion]:
        """加载测评题库"""
        questions_file = Path("b/data/assessment/questions.json")
        questions_file.parent.mkdir(parents=True, exist_ok=True)
        
        if not questions_file.exists():
            default_questions = [
                {
                    "question_id": "Q1",
                    "question_text": "你更喜欢哪种工作环境？",
                    "dimension": "work_style",
                    "options": [
                        {"text": "独立安静的空间", "score": {"independent": 0.8}},
                        {"text": "团队协作的氛围", "score": {"collaborative": 0.8}}
                    ]
                }
            ]
            with open(questions_file, "w") as f:
                json.dump(default_questions, f, indent=2)
            logger.info("已创建默认测评题库")
        
        with open(questions_file, "r") as f:
            return [AssessmentQuestion(**q) for q in json.load(f)]
    
    def _load_job_profiles(self) -> Dict[str, Dict[str, float]]:
        """加载岗位特征数据"""
        profiles_file = Path("b/data/assessment/job_profiles.json")
        profiles_file.parent.mkdir(parents=True, exist_ok=True)
        
        if not profiles_file.exists():
            default_profiles = {
                "Data Scientist": {
                    "analytical": 0.9,
                    "creative": 0.7,
                    "collaborative": 0.6
                }
            }
            with open(profiles_file, "w") as f:
                json.dump(default_profiles, f, indent=2)
            logger.info("已创建默认岗位特征数据")
        
        with open(profiles_file, "r") as f:
            return json.load(f)
    
    def conduct_assessment(self, user_id: str, answers: Dict[str, str]) -> AssessmentResult:
        """执行职业测评"""
        # 计算维度得分
        dimension_scores = {}
        for q_id, answer in answers.items():
            question = next((q for q in self.questions if q.question_id == q_id), None)
            if not question:
                continue
                
            selected_option = next(
                (opt for opt in question.options if opt["text"] == answer),
                None
            )
            if not selected_option:
                continue
                
            for dim, score in selected_option["score"].items():
                if dim in dimension_scores:
                    dimension_scores[dim] += score * question.weight
                else:
                    dimension_scores[dim] = score * question.weight
        
        # 标准化得分(0-1)
        max_score = max(dimension_scores.values()) if dimension_scores else 1
        for dim in dimension_scores:
            dimension_scores[dim] /= max_score
        
        # 匹配岗位
        job_matches = {}
        for job, profile in self.job_profiles.items():
            compatibility = self._calculate_compatibility(dimension_scores, profile)
            job_matches[job] = compatibility
        
        # 排序推荐
        recommended_jobs = sorted(
            job_matches.items(),
            key=lambda x: x[1],
            reverse=True
        )[:5]
        
        return AssessmentResult(
            user_id=user_id,
            dimensions=dimension_scores,
            recommended_jobs=[job for job, _ in recommended_jobs],
            compatibility_scores=dict(recommended_jobs),
            timestamp=datetime.now().isoformat()
        )
    
    def _calculate_compatibility(self, user_scores: Dict[str, float], 
                               job_profile: Dict[str, float]) -> float:
        """计算岗位匹配度"""
        # 余弦相似度
        dimensions = set(user_scores.keys()).union(set(job_profile.keys()))
        user_vec = np.array([user_scores.get(d, 0) for d in dimensions])
        job_vec = np.array([job_profile.get(d, 0) for d in dimensions])
        
        dot_product = np.dot(user_vec, job_vec)
        user_norm = np.linalg.norm(user_vec)
        job_norm = np.linalg.norm(job_vec)
        
        return dot_product / (user_norm * job_norm) if user_norm * job_norm > 0 else 0
    
    def generate_report(self, result: AssessmentResult) -> Dict[str, Any]:
        """生成测评报告"""
        return {
            "user_id": result.user_id,
            "assessment_date": result.timestamp,
            "dimension_scores": result.dimensions,
            "top_recommendations": [
                {
                    "job": job,
                    "match_score": result.compatibility_scores[job],
                    "skills": self.kg.get_job_skills(job),
                    "salary_range": self._get_salary_range(job)
                }
                for job in result.recommended_jobs
            ],
            "development_suggestions": self._generate_suggestions(result)
        }
    
    def _get_salary_range(self, job_title: str) -> Dict[str, float]:
        """获取岗位薪资范围"""
        # 这里可以集成薪酬预测模块
        return {
            "min": 10000,
            "median": 20000,
            "max": 50000
        }
    
    def _generate_suggestions(self, result: AssessmentResult) -> List[str]:
        """生成发展建议"""
        suggestions = []
        
        # 基于优势维度的建议
        top_dimension = max(result.dimensions.items(), key=lambda x: x[1])[0]
        if top_dimension == "analytical":
            suggestions.append("加强数据分析和统计建模能力")
        elif top_dimension == "creative":
            suggestions.append("参与创新项目以发挥创造力")
        
        # 基于推荐岗位的建议
        if result.recommended_jobs:
            suggestions.append(
                f"关注{result.recommended_jobs[0]}岗位的核心技能要求"
            )
        
        return suggestions

if __name__ == "__main__":
    # 示例使用
    kg = JobKnowledgeGraph()
    assessor = CareerAssessment(kg)
    
    # 模拟用户回答
    test_answers = {
        "Q1": "独立安静的空间",
        "Q2": "解决复杂的技术问题",
        "Q3": "分析数据并发现规律"
    }
    
    # 执行测评
    result = assessor.conduct_assessment("user123", test_answers)
    print("\n测评结果:")
    print(f"用户维度得分: {result.dimensions}")
    print(f"推荐岗位: {result.recommended_jobs}")
    
    # 生成报告
    report = assessor.generate_report(result)
    print("\n测评报告:")
    print(json.dumps(report, indent=2, ensure_ascii=False))